﻿// Copyright (c) 2014 Takashi Yoshizawa

using System;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace Yoshizawa
{
    public static class MessageDialog
    {
        static MessageDialog()
        {
            Title = Assembly.GetExecutingAssembly().GetName().Name;
        }

        public static string Title
        {
            get;
            set;
        }

        public static bool IsSilent
        {
            get;
            set;
        }

        public static void Info(object value, params object[] args)
        {
            Show(MessageBoxIcon.Information, value, args);
        }

        public static void Warn(object value, params object[] args)
        {
            Show(MessageBoxIcon.Warning, value, args);
        }

        public static void Error(object value, params object[] args)
        {
            Show(MessageBoxIcon.Error, value, args);
        }

        public static bool Confirm(object value, params object[] args)
        {
            if (IsSilent)
            {
                return true;
            }

            var msg = FormatMessage(value, args);

            using (var form = new Form())
            {
                DisplayPositionAdjustment(form);

                return DialogResult.Yes == MessageBox.Show(
                    form,
                    msg,
                    Title,
                    MessageBoxButtons.YesNo,
                    MessageBoxIcon.Exclamation,
                    MessageBoxDefaultButton.Button1);
            }
        }

        private static void Show(MessageBoxIcon icon, object value, params object[] args)
        {
            if (IsSilent)
            {
                return;
            }

            var msg = FormatMessage(value, args);

            using (var form = new Form())
            {
                DisplayPositionAdjustment(form);

                MessageBox.Show(
                    form,
                    msg,
                    Title,
                    MessageBoxButtons.OK,
                    icon);
            }
        }

        private static void DisplayPositionAdjustment(Form form)
        {
            IntPtr hwnd = Process.GetCurrentProcess().MainWindowHandle;
            NativeMethods.RECT rect = new NativeMethods.RECT();
            NativeMethods.GetWindowRect(hwnd, out rect);

            form.Opacity = 0;
            form.Width = 0;
            form.Height = 0;
            form.Left = rect.Left;
            form.Top = rect.Top;
            form.ShowInTaskbar = false;
            form.FormBorderStyle = FormBorderStyle.FixedToolWindow;
            form.WindowState = FormWindowState.Minimized;
            form.StartPosition = FormStartPosition.Manual;
            form.TopMost = true;
        }

        private static string FormatMessage(object value, params object[] args)
        {
            return 0 < args.Length
                ? string.Format(CultureInfo.CurrentCulture, value.ToString(), args)
                : value.ToString();
        }

        private static class NativeMethods
        {
            [DllImport("user32.dll")]
            [return: MarshalAs(UnmanagedType.Bool)]
            internal static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);

            internal struct RECT
            {
                public int Left;
                public int Top;
                public int Right;
                public int Bottom;
            }
        }
    }
}
